package plenprojects.chatservice;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import plenprojects.dao.ChatServiceDao;
import plenprojects.model.UserDetails;
import plenprojects.security.Permission;
import plenprojects.security.PermissionType;
import plenprojects.security.SecurityToken;

public class ChatService {
	
	private final Map<String, ChatRoom> chatRooms = new HashMap<String, ChatRoom>();
	private final TokenContainer tokens = new TokenContainer();
	private ChatServiceDao dao;
	
	public void addRoom(ChatRoom room) {
		
		chatRooms.put(room.getName(), room);
	}
	
	public ChatRoom getRoom(String name) {
		
		return chatRooms.get(name);
	}
	
	public boolean roomExists(String name) {
		
		return chatRooms.containsKey(name);
	}
	
	public List<String> getListOfChatRooms() {
		
		List<String> list = new ArrayList<String>();
		
		for(String key : chatRooms.keySet()) {
			
			list.add(key);
		}
		
		return list;
	}
	
	public UserDetails getUserInfo(String username) {
		
		return dao.getDetailsFromUsername(username);
	}
	
	public SecurityToken generatePublicAccessToken(String username) {//TODO make difference between public and private chat rooms
		
		UUID uuid = UUID.randomUUID();
		
		SecurityToken token = new SecurityToken(uuid.toString(), username);
		
		for(ChatRoom room : chatRooms.values()) {
			
			token.addPermission(new Permission(room.getName(), PermissionType.CAN_JOIN));
		}
		
		tokens.submitToken(token);
		
		return token;
	}
	
	public void invalidateToken(String tokenValue) {
		
		SecurityToken token = tokens.getTokenByValue(tokenValue);
		
		for(ChatRoom room : chatRooms.values()) {
			
			room.removeUser(token.getUsername());
		}
		
		tokens.invalidateToken(tokens.getTokenByValue(tokenValue));
	}
	
	public boolean hasToken(String username) {
		
		return tokens.getTokenByUsername(username) != null;
	}
	
	public boolean isValid(String tokenValue) {
		
		return tokens.getTokenByValue(tokenValue) != null;
	}
	
	public boolean isAuthorized(String tokenValue, String room, PermissionType type) {
		
		SecurityToken token = tokens.getTokenByValue(tokenValue);
		
		for(Permission p : token.getPermissions()) {
			
			if(p.getChatroom().equals(room) && p.getType().equals(type)) {
				
				return true;
			}
		}
		
		return false;
	}

	public void setDao(ChatServiceDao dao) {
		
		this.dao = dao;
	}
	
	public SecurityToken toToken(String tokenValue) {
		
		return tokens.getTokenByValue(tokenValue);
	}
	
	public SecurityToken usernameToToken(String username) {
		
		return tokens.getTokenByUsername(username);
	}
	
}
